package com.mowh.multithreading.producer.consumer.table;

/**
 * @author mowh1gd
 * @create 2023/11/15 14:50
 */
public class Table {//扮演Channel角色
    private final String[] buffer;//队列，队列中元素String cake扮演Data角色
    private int tail;//队列尾部索引
    private int head;//队列头部索引
    private int count;//桌上蛋糕总数

    public Table(int count) {//构造函数需指定队列长度
        this.buffer = new String[count];
        this.tail = 0;
        this.head = 0;
        this.count = 0;
    }

    public synchronized void put(String cake) throws InterruptedException {//采用Guarded Suspension模式
        System.out.println(Thread.currentThread().getName() + " puts " + cake);
        while (count >= buffer.length) {//守护条件为当前桌上蛋糕总数count不能超过buffer长度。这里不满足守护条件，所以等待。
            wait();
        }
        buffer[tail] = cake;//守护条件满足后，把蛋糕放在当前尾部索引的地方。
        tail = (tail + 1) % buffer.length;//放完后，更新尾部索引，即加1，需模掉buffer长度。
        count++;//当前桌上蛋糕总数加1
        notifyAll();
    }
    public synchronized String take() throws InterruptedException {//采用Guarded Suspension模式
        while (count <= 0) {//守护条件为当前桌上蛋糕总数count必须大于0。这里不满足守护条件，所以等待。
            wait();
        }
        String cake = buffer[head];//守护条件满足后，在当前头部索引的地方取出蛋糕。
        head = (head + 1) % buffer.length;//取完后，更新头部索引，即加1，需模掉buffer长度。
        count--;//当前桌上蛋糕总数减1
        notifyAll();
        System.out.println(Thread.currentThread().getName() + " takes " + cake);
        return cake;
    }
}
